package com.tubang.organization.controller;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.tubang.common.redis.RedisGeneratekeyUtils;
import com.tubang.common.util.*;
import com.tubang.component.entity.CompanyEntity;
import com.tubang.component.entity.UserEntity;
import com.tubang.component.service.ICompanyService;
import com.tubang.component.service.IRedisService;
import com.tubang.component.service.IUserService;
import com.tubang.component.util.RequestUtil;
import com.tubang.component.vo.CompanyVo;
import com.tubang.component.vo.UserVo;
import com.tubang.organization.dto.AppLoginBySmsDto;
import com.tubang.organization.dto.FindPasswordDto;
import com.tubang.organization.entity.RoleEntity;
import com.tubang.organization.service.IMenuService;
import com.tubang.organization.service.IRoleMenuService;
import com.tubang.organization.service.IRoleService;
import com.tubang.organization.service.IUserRoleService;
import com.tubang.organization.vo.LoginVo;
import com.tubang.organization.vo.MenuVo;
import com.tubang.organization.vo.RoleVo;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

@RestController
public class LoginController {
    private Logger logger = LoggerFactory.getLogger(getClass());

    @Resource
    private IUserService userService;
    @Resource
    private IUserRoleService userRoleService;

    @Resource
    private IRedisService redisService;
    @Resource
    private ICompanyService companyService;

    @Resource
    private IRoleService roleService;
    @Resource
    private IRoleMenuService roleMenuService;
    @Resource
    private IMenuService menuService;


    /**
     * @return ResultData 返回类型
     * @throws
     * @Title login
     * @Description 登录
     */
    @PostMapping(value = "login")
    public ResultData login(HttpServletRequest request, HttpServletResponse response) {
        String receivePostJson = RequestUtil.receivePostJson(request);
        UserVo userVo = GsonQuick.getGson().fromJson(receivePostJson, UserVo.class);
        // shiro登陆验证
        UsernamePasswordToken token = new UsernamePasswordToken(userVo.getMobile(), EncryptorUtil.AesEncrypt(userVo.getPassword()));
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(token);
        } catch (UnknownAccountException ex) {
            logger.error("Account wrong  ：" + userVo.getMobile());
            return ResultData.result(false).setMsg(MsgCode.USER_ACCOUNT_IS_WRONG_DESC).setCode(MsgCode.USER_ACCOUNT_IS_WRONG);
        } catch (IncorrectCredentialsException ex) {
            ex.printStackTrace();
            logger.error("Password wrong :" + userVo.getPassword());
            return ResultData.result(false).setMsg(MsgCode.USER_PASSWOR_IS_WRONG_DESC).setCode(MsgCode.USER_PASSWOR_IS_WRONG);
        } catch (LockedAccountException ex) {
            logger.error("Account locked");
            return ResultData.result(false).setMsg(MsgCode.USER_ACCOUNT_IS_LOCK_DESC).setCode(MsgCode.USER_ACCOUNT_IS_LOCK);
        } catch (Exception e) {
            logger.error("ShiroLoginManager Exception： " + e.getMessage());
            e.printStackTrace();
            return ResultData.result(false).setData(e.getMessage());
        }

        try {
            //根据用户手机号查询用户
            EntityWrapper<UserEntity> entityWrapper = new EntityWrapper<>();
            entityWrapper.eq("mobile", userVo.getMobile());
            UserEntity user = userService.selectOne(entityWrapper);

            // 当验证都通过后，把用户信息放在redis里
            redisService.set(RedisGeneratekeyUtils.GeneratedStringUserInfoKey(user.getId()), user);
            LoginVo loginVo = new LoginVo();

//			UserRoleEntity userRole = new UserRoleEntity();
//			userRole.setUserId(user.getId());
//			EntityWrapper<UserRoleEntity> userRoleEntity = new EntityWrapper<>(userRole);
//
//			List<UserRoleEntity> userRoles = userRoleService.selectList(userRoleEntity);
//
//
//			ArrayList<MenuVo> menuList = Lists.newArrayList();
//
//			List<RoleEntity> roles = Lists.newArrayList();
//			for (UserRoleEntity ur : userRoles) {
//				RoleEntity role = new RoleEntity();
//				role.setId(ur.getRoleId());
//				EntityWrapper<RoleEntity> roleEntity = new EntityWrapper<>(role);
//				RoleEntity rs = roleService.selectOne(roleEntity);
//				roles.add(rs);
//			}
//
//			List<RoleMenuEntity> roleMenus = Lists.newArrayList();
//			for (RoleEntity r : roles) {
//				RoleMenuEntity roleMenu = new RoleMenuEntity();
//				roleMenu.setRoleId(r.getId());
//				EntityWrapper<RoleMenuEntity> roleMenuEntity = new EntityWrapper<>(roleMenu);
//				List<RoleMenuEntity> rms = roleMenuService.selectList(roleMenuEntity);
//				for (RoleMenuEntity rm : rms) {
//					roleMenus.add(rm);
//				}
//			}
//			logger.info("roleMenus: {}", GsonQuick.getGson().toJson(roleMenus));
//
//			HashSet<MenuEntity> menus = Sets.newHashSet();
//			for (RoleMenuEntity rm : roleMenus) {
//				MenuEntity menu = new MenuEntity();
//				menu.setId(rm.getMenuId());
//				EntityWrapper<MenuEntity> menuEntity = new EntityWrapper<>(menu);
//				MenuEntity mes = menuService.selectOne(menuEntity);
//				menus.add(mes);
//			}
//
//			logger.info("所有菜单列表：{} " + GsonQuick.getGson().toJson(menus));
////			if (menus.isEmpty()) {
////				return ResultData.result(false).setMsg("该用户没有任何权限");
////			}
//			for (MenuEntity m : menus) {
//				if ("0".equals(m.getType())) {
//					MenuVo map = BeanMapper.map(m, MenuVo.class);
//
//					MenuEntity menuEntity = new MenuEntity();
//					menuEntity.setParentId(m.getId());
//					EntityWrapper<MenuEntity> wrapper = new EntityWrapper<>(menuEntity);
//					List<MenuEntity> childList = menuService.selectList(wrapper);
//
//					List<MenuVo> childListVo = BeanMapper.mapList(childList, MenuVo.class);
//					map.setChildList(childListVo);
//
//					menuList.add(map);
//				}
//			}
            UserVo userInfo = BeanMapper.map(user, UserVo.class);

            loginVo.setUserVo(userInfo);
            //loginVo.setMeunList(menuList);
            //loginVo.setRoles(BeanMapper.mapList(roles, RoleVo.class));

            //查询当前用户所属组织的信息
            String companyId = user.getCompanyId();
            CompanyEntity company = companyService.selectById(companyId);
            if (company == null) {
                return ResultData.result(true).setData(loginVo);
            }
            CompanyVo companyVo = loginVo.getCompanyVo();
            if (companyVo == null) companyVo = new CompanyVo();
            companyVo.setCompanyId(company.getId());
            companyVo.setName(company.getName());
            companyVo.setCompanyName(company.getName());
            companyVo.setCompanyType(company.getType());
            //查询当前组织的负责人
            UserEntity cuser = userService.selectCompanyUserAdminByCompanyId(company.getId(), company.getType());
            if (cuser != null) {
                companyVo.setUserId(cuser.getId());
                companyVo.setUserName(cuser.getName());
                companyVo.setUserMobile(cuser.getMobile());
            }
            loginVo.setCompanyVo(companyVo);

            RoleEntity roleEntity = roleService.selectById(user.getUserType());
            if (roleEntity == null) return ResultData.result(true).setData(loginVo);
            RoleVo roleVo = BeanMapper.map(roleEntity, RoleVo.class);
            loginVo.setRoleVo(roleVo);
            List<MenuVo> menuVos = roleMenuService.selectMenuListByRoleId(roleEntity.getId());
            loginVo.setMeunVos(menuVos);
            return ResultData.result(true).setData(loginVo);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("[login]==> method[login],错误原因：[{}]", e.getMessage());
            return ResultData.result(false).setData(e.getMessage());
        }
    }

    /**
     * @param userId 用户id
     * @return ResultData 返回类型
     * @Title logout
     * @Description 注销
     */
    @GetMapping("logout")
    public ResultData logout(@RequestParam(required = true) String userId) {
        try {
            logger.info("[logout]==> method[logout],请求：[{}]", GsonQuick.getGson().toJson(userId));
            String redisUserInfoKey = RedisGeneratekeyUtils.GeneratedStringUserInfoKey(userId);
            Object user = redisService.get(redisUserInfoKey);
            if (user == null) {
                return ResultData.result(false).setMsg(MsgCode.USER_IS_NOT_LOGIN_DESC).setCode(MsgCode.USER_IS_NOT_LOGIN);
            }
            redisService.remove(redisUserInfoKey);
            Subject subject = SecurityUtils.getSubject();
            subject.logout();
            return ResultData.result(true).setMsg(MsgCode.DEFAULT_SUCCESS_MSG).setCode(MsgCode.SUCCESS);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("[logout] ==> method[logout]，用户注销系统异常，异常原因为 ： [{}]", e.getMessage());
            return ResultData.result(false).setData(e.getMessage());
        }
    }

    /**
     * @return ResultData 返回类型
     * @throws
     * @Title login
     * @Description 通过短信验证码登录
     */
    @PostMapping("loginBySms")
    public ResultData loginBySms(HttpServletRequest request, HttpServletResponse response) {
        try {
            String receivePostJson = RequestUtil.receivePostJson(request);
            AppLoginBySmsDto appLoginBySmsDto = GsonQuick.getGson().fromJson(receivePostJson, AppLoginBySmsDto.class);
            //根据用户手机号查询用户
            EntityWrapper<UserEntity> entityWrapper = new EntityWrapper<>();
            entityWrapper.eq("mobile", appLoginBySmsDto.getMobile());
            UserEntity user = userService.selectOne(entityWrapper);
            if (user == null) {
                return ResultData.result(false).setMsg(MsgCode.USER_MOBILE_IS_NOT_REGISTER_DESC).setCode(MsgCode.USER_MOBILE_IS_NOT_REGISTER);
            }
            // 判断验证码是否相等
            String captcha = redisService.get(RedisGeneratekeyUtils.GeneratedStringSmsCaptcha(appLoginBySmsDto.getMobile())).toString();
            if (!StringUtils.equals(captcha, appLoginBySmsDto.getSmsCaptcha())) {
                return ResultData.result(false).setMsg(MsgCode.USER_MOBILE_SMS_CAPTCHA_DESC).setStatus(MsgCode.USER_MOBILE_SMS_CAPTCHA);
            }
            return ResultData.result(true).setData(user);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("[logout] ==> method[loginBySms]，app通过短信验证码登录，异常原因为 ： [{}]", e.getMessage());
            return ResultData.result(false).setData(e.getMessage());
        }
    }

    /**
     * @return ResultData 返回类型
     * @throws
     * @Title login
     * @Description 忘记密码
     */
    @PostMapping("findPassword")
    public ResultData findPassword(HttpServletRequest request, HttpServletResponse response) {
        try {
            String receivePostJson = RequestUtil.receivePostJson(request);
            FindPasswordDto appFindPasswordDto = GsonQuick.getGson().fromJson(receivePostJson, FindPasswordDto.class);
            //根据用户手机号查询用户
            EntityWrapper<UserEntity> entityWrapper = new EntityWrapper<>();
            entityWrapper.eq("mobile", appFindPasswordDto.getMobile());
            UserEntity user = userService.selectOne(entityWrapper);
            if (user == null) {
                return ResultData.result(false).setMsg(MsgCode.USER_MOBILE_IS_NOT_REGISTER_DESC).setCode(MsgCode.USER_MOBILE_IS_NOT_REGISTER);
            }
            // 判断手机短信验证码是否相等
            String captcha = redisService.get(RedisGeneratekeyUtils.GeneratedStringSmsCaptcha(appFindPasswordDto.getMobile())).toString();
            if (!StringUtils.equals(captcha, appFindPasswordDto.getSmsCaptcha())) {
                return ResultData.result(false).setMsg(MsgCode.USER_MOBILE_SMS_CAPTCHA_DESC).setStatus(MsgCode.USER_MOBILE_SMS_CAPTCHA);
            }
            if (!StringUtils.equals(appFindPasswordDto.getNewPassword(), appFindPasswordDto.getConfirmPassword())) {
                return ResultData.result(false).setMsg(MsgCode.PASSWORD_IS_NOT_SAME_DESC).setStatus(MsgCode.PASSWORD_IS_NOT_SAME);
            }
            user.setPassword(EncryptorUtil.AesEncrypt(appFindPasswordDto.getConfirmPassword()));
            userService.insertOrUpdate(user);
            return ResultData.result(true);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("[logout] ==> method[loginBySms]，app通过短信验证码登录，异常原因为 ： [{}]", e.getMessage());
            return ResultData.result(false).setData(e.getMessage());
        }
    }

}
